package com.ctshk.rpc.season.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SeasonType;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.localfun.dto.LocalFunPriceRemainderDTO;
import com.ctshk.rpc.localfun.service.ILocalFunProductService;
import com.ctshk.rpc.season.dto.PackageProductCostDTO;
import com.ctshk.rpc.season.dto.SeasonFixedProductPackageLocalFunDTO;
import com.ctshk.rpc.season.entity.SeasonFixedProductPackageLocalFun;
import com.ctshk.rpc.season.mapper.SeasonFixedProductPackageLocalFunMapper;
import com.ctshk.rpc.season.req.PassengerReq;
import com.ctshk.rpc.season.req.SeasonFixedProductPackageLocalFunReq;
import com.ctshk.rpc.season.req.UpdatePackageProductReq;
import com.ctshk.rpc.season.service.ISeasonFixedProductPackageLocalFunService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 套票-固定套票单项产品打包-景点门票表 服务实现类
 * </p>
 *
 * @author 杨林
 * @since 2021-03-09
 */
@Slf4j
@DubboService
public class SeasonFixedProductPackageLocalFunServiceImpl extends ServiceImpl<SeasonFixedProductPackageLocalFunMapper, SeasonFixedProductPackageLocalFun> implements ISeasonFixedProductPackageLocalFunService {

    @Autowired
    private SeasonFixedProductPackageLocalFunMapper seasonFixedProductPackageLocalFunMapper;

    @DubboReference
    private ILocalFunProductService localFunProductService;

    /* @MethodName: 获取本地玩乐的价格
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/26 19:36
     **/
    @Override
    public PackageProductCostDTO getLocalFunProductPrice(Long productId, LocalDate departureDate, Long userId, Integer channelType, Long attrId1, Long attrId2) {
        PackageProductCostDTO costDTO = new PackageProductCostDTO();
        try {
            log.info("调用当地玩乐服务获取价格入参channelType:{},productId:{},departureDate:{},userId:{},attrId1:{},attrId2:{}", channelType, productId, departureDate, userId, attrId1, attrId2);
            LocalFunPriceRemainderDTO result = localFunProductService.findLocalFunSalePriceInfoHandle(channelType, productId, departureDate, userId, attrId1, attrId2);
            log.info("调用当地玩乐服务获取价格值:{}", JSON.toJSONString(result));
            if (null != result && result.getSolidNumber() > 0) {
                costDTO.setCostPrice(result.getPrice());
                costDTO.setStock(result.getSolidNumber());
            }
        } catch (Exception e) {
            log.error("调用当地玩乐服务获取价格发生异常:{}", e);
        }

        return costDTO;
    }

    /* @MethodName: 固定套票默认当地玩乐的价格
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/19 13:32
     **/
    @Override
    public BigDecimal getDefaultLocalFunPrice(Long packageId, LocalDate queryDate, Long userId, Integer channelType) {
        BigDecimal bd = BigDecimal.ZERO;
        SeasonFixedProductPackageLocalFun localFun = seasonFixedProductPackageLocalFunMapper.selectOne(
                new QueryWrapper<SeasonFixedProductPackageLocalFun>().lambda().
                        eq(SeasonFixedProductPackageLocalFun::getIsDefault, SeasonType.YES_DEFAULT.getCode()).
                        eq(SeasonFixedProductPackageLocalFun::getIsDeleted, IsDeletedCode.NO.getCode()).
                        eq(SeasonFixedProductPackageLocalFun::getPackageId, packageId)
        );
        if (null != localFun) {
            bd = getLocalFunProductPrice(localFun.getProductId(), queryDate, userId, channelType, null, null).getCostPrice();
        }
        return bd;
    }

    @Override
    public List<SeasonFixedProductPackageLocalFunDTO> getLocalFunByPackageId(Long packageId, LocalDate queryDate, Long userId, Integer channelType) {
        List<SeasonFixedProductPackageLocalFun> resultList = seasonFixedProductPackageLocalFunMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageLocalFun>().lambda().
                        eq(SeasonFixedProductPackageLocalFun::getIsDeleted, IsDeletedCode.NO.getCode()).
                        eq(SeasonFixedProductPackageLocalFun::getPackageId, packageId)
        );
        List<SeasonFixedProductPackageLocalFunDTO> resultDtoList = new ArrayList<>();
        if (null != resultList && resultList.size() > 0) {
            for (SeasonFixedProductPackageLocalFun result : resultList) {
                SeasonFixedProductPackageLocalFunDTO resultDto = EntityUtil.copy(result, SeasonFixedProductPackageLocalFunDTO.class);
                resultDto.setCost(getLocalFunProductPrice(result.getProductId(), queryDate, userId, channelType, null, null).getCostPrice());
                resultDtoList.add(resultDto);
            }
        }
        return resultDtoList;
    }

    @Override
    public List<SeasonFixedProductPackageLocalFunDTO> getDefaultLocalFunData(Long packageId, LocalDate queryDate, Long userId, Integer channelType) {
        List<SeasonFixedProductPackageLocalFun> resultList = seasonFixedProductPackageLocalFunMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageLocalFun>().lambda().
                        eq(SeasonFixedProductPackageLocalFun::getIsDefault, SeasonType.YES_DEFAULT.getCode()).
                        eq(SeasonFixedProductPackageLocalFun::getIsDeleted, IsDeletedCode.NO.getCode()).
                        eq(SeasonFixedProductPackageLocalFun::getPackageId, packageId)
        );
        List<SeasonFixedProductPackageLocalFunDTO> resultDtoList = new ArrayList<>();
        if (null != resultList && resultList.size() > 0) {
            for (SeasonFixedProductPackageLocalFun result : resultList) {
                SeasonFixedProductPackageLocalFunDTO resultDto = EntityUtil.copy(result, SeasonFixedProductPackageLocalFunDTO.class);
                resultDto.setCost(getLocalFunProductPrice(result.getProductId(), queryDate, userId, channelType, null, null).getCostPrice());
                resultDtoList.add(resultDto);
            }
        }
        return resultDtoList;
    }

    /* @MethodName: 批量保存 景点门票产品信息
     * @Description: TODO
     * @Param: userId 用户id  productId 产品id packageId 打包id  scenicReqList 景点门票集合
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/9 18:27
     **/
    @Override
    public void batchLocalFunProduct(Long userId, Long packageId, List<SeasonFixedProductPackageLocalFunReq> localFunList) {
        LocalDateTime now = LocalDateTime.now();
        List<SeasonFixedProductPackageLocalFun> lfList = localFunList.stream().map(
                localFunReq -> {
                    SeasonFixedProductPackageLocalFun scenic = EntityUtil.copy(localFunReq, SeasonFixedProductPackageLocalFun.class);
                    scenic.setCreateId(userId);
                    scenic.setPackageId(packageId);
                    scenic.setGmtCreate(now);
                    scenic.setId(IdWorker.getId());
                    scenic.setIsDeleted(IsDeletedCode.NO.getCode());
                    return scenic;
                }
        ).collect(Collectors.toList());
        seasonFixedProductPackageLocalFunMapper.insertBatchSomeColumn(lfList);
    }

    /* @MethodName: 获取固定套票 景点门票信息
     * @Description: TODO
     * @Param: fixedSeasonId 固定套票id   packageId 产品打包id
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/11 13:40
     **/
    @Override
    public List<SeasonFixedProductPackageLocalFunDTO> getSeasonFixedProductLocalFunDtoList(Long packageId) {
        List<SeasonFixedProductPackageLocalFun> productPackageLocalFunList = getSeasonFixedProductLocalFunList(packageId);
        List<SeasonFixedProductPackageLocalFunDTO> list = new LinkedList<>();
        if (null != productPackageLocalFunList && productPackageLocalFunList.size() > 0) {
            list = productPackageLocalFunList.stream().map(
                    localFun -> {
                        SeasonFixedProductPackageLocalFunDTO ScenicDto = EntityUtil.copy(localFun, SeasonFixedProductPackageLocalFunDTO.class);
                        return ScenicDto;
                    }
            ).collect(Collectors.toList());
        }
        return list;
    }

    /* @MethodName: 删除原来的景点票产品
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/12 16:26
     **/
    @Override
    public void deletePreviousLocalFun(Long userId, Long packageId) {
        LocalDateTime now = LocalDateTime.now();
        UpdateWrapper<SeasonFixedProductPackageLocalFun> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("modified_id", userId);//修改人
        updateWrapper.set("is_deleted", IsDeletedCode.YES.getCode());//删除
        updateWrapper.set("gmt_modified", now);//修改时间
        updateWrapper.eq("package_id", packageId);
        seasonFixedProductPackageLocalFunMapper.update(null, updateWrapper);
    }


    /* @MethodName: 获取景点门票的成本差价
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/23 13:49
     **/
    @Override
    public List<SeasonFixedProductPackageLocalFunDTO> getLocalFunDifferencePrice(UpdatePackageProductReq req) {
        Long packageId = req.getPackageId();
        //多少人
        Integer num = req.getPassengerReqList().stream().mapToInt(passenger -> passenger.getPassengerNum()).sum();
        BigDecimal num1 = new BigDecimal(String.valueOf(num));
        LocalDate queryDate = req.getStartDate();
        List<SeasonFixedProductPackageLocalFunDTO> list = new LinkedList<>();
        SeasonFixedProductPackageLocalFunDTO defaultDto = getSeasonFixedDefaultProductLocalFun(packageId, queryDate, req.getPassengerReqList(), req.getUserId());
        list.add(defaultDto);
        BigDecimal flagCost = defaultDto.getCost();
        List<SeasonFixedProductPackageLocalFun> localFunList = getLocalFun(packageId, SeasonType.NO_DEFAULT.getCode());
        localFunList.stream().forEach(
                localFun -> {
                    Long localFunProductId = localFun.getProductId();
                    SeasonFixedProductPackageLocalFunDTO localFunDto = EntityUtil.copy(localFun, SeasonFixedProductPackageLocalFunDTO.class);
                    BigDecimal singleCost = BigDecimal.ZERO;
                    BigDecimal scenicCost = singleCost.multiply(num1);
                    localFunDto.setCost(scenicCost);
                    if (scenicCost.compareTo(BigDecimal.ZERO) == 0) {//表示没有库存
                        localFunDto.setPriceDifference("售罄");
                    } else {
                        localFunDto.setPriceDifference(String.valueOf(flagCost.subtract(scenicCost)));//减法
                    }
                    localFunDto.setSingleCost(singleCost);//单间单晚成本
                    list.add(localFunDto);
                });


        return list;
    }

    public SeasonFixedProductPackageLocalFunDTO getSeasonFixedDefaultProductLocalFun(Long packageId, LocalDate queryDate, List<PassengerReq> passengerReqList, Long userId) {
        SeasonFixedProductPackageLocalFun localFun = getLocalFun(packageId, SeasonType.YES_DEFAULT.getCode()).get(0);
        SeasonFixedProductPackageLocalFunDTO localFunDTO = EntityUtil.copy(localFun, SeasonFixedProductPackageLocalFunDTO.class);
        BigDecimal localFunCost = BigDecimal.ZERO;

        //旅客类型集合
        Integer num = passengerReqList.stream().mapToInt(passenger -> passenger.getPassengerNum()).sum();
        BigDecimal num1 = new BigDecimal(String.valueOf(num));
        BigDecimal totalCost = localFunCost.multiply(num1);
        localFunDTO.setCost(totalCost);
        if (localFunCost.compareTo(BigDecimal.ZERO) == 0) {
            localFunDTO.setPriceDifference("售罄");
        } else {
            localFunDTO.setPriceDifference("0");
        }
        return localFunDTO;
    }


    /* @MethodName: 获取固定套票 景点门票信息
     * @Description: TODO
     * @Param: fixedSeasonId 固定套票id   packageId 产品打包id
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/11 13:40
     **/
    private List<SeasonFixedProductPackageLocalFun> getSeasonFixedProductLocalFunList(Long packageId) {
        QueryWrapper<SeasonFixedProductPackageLocalFun> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("package_id", packageId);
        queryWrapper.eq("is_deleted", IsDeletedCode.NO.getCode());
        return seasonFixedProductPackageLocalFunMapper.selectList(queryWrapper);
    }


    /* @MethodName: 获取景点门票信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/2 11:19
     **/
    private List<SeasonFixedProductPackageLocalFun> getLocalFun(Long packageId, Integer isDefault) {
        return seasonFixedProductPackageLocalFunMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageLocalFun>().lambda()
                        .eq(SeasonFixedProductPackageLocalFun::getIsDefault, IsDeletedCode.NO.getCode())
                        .eq(SeasonFixedProductPackageLocalFun::getPackageId, packageId)
                        .eq(SeasonFixedProductPackageLocalFun::getIsDefault, isDefault)
        );

    }
}
